import React, { useContext, useEffect, useImperativeHandle, useRef, useState } from 'react';
import dayjs from 'dayjs';
import { message } from 'antd';
import { detailPlan, detailPlanDate, detailPlanOwner, detailPlanUser, stageStartTime, userConfig } from '@/utils/data';
import { getScheduleApi, submitScheduleApi } from '@/request/story';
import { useHeight } from '@/utils/hooks/height';
import SchedulePlanLeft from './schedulePlanLeft';
import SchedulePlanRight from './schedulePlanRight';

import s from './index.module.css';
import PlanModal from './planModal';

interface PlanType {
  title: string;
  key: string;
  value: string;
  time?: string;
  children?: PlanType[];
}

interface TypeOf {
  title: string;
  key: string;
}

const SchedulePlan = ({ detailData, lockInfo, setLockInfo }, ref) => {
  const [plan, setPlan] = useState<PlanType[]>([
    { title: '技术Owner', key: 'index1', value: '-' },
    { title: '提测环境', key: 'index2', value: '-' },
    { title: '测试范围', key: 'testRange', value: '' },
  ]);
  const [submitData, setSubmitData] = useState<any>(null);
  const [planModalOpen, setPlanModalOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  const { height } = useHeight(530);

  useImperativeHandle(ref, () => {
    return {
      getData: () => submitData,
    };
  });

  const getRandomId = () => {
    return Math.random().toString(32).slice(2);
  };

  // 复制内容
  const copyPlanFn = (str) => {
    try {
      if (navigator.clipboard && window.isSecureContext) {
        navigator.clipboard.writeText(str);
        message.success('排期计划已复制');
      } else {
        const textArea = document.createElement('textarea');
        textArea.value = str;
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();
        document.execCommand('copy');
        message.success('复制成功');
        document.body.removeChild(textArea);
      }
    } catch (error) {
      message.error('复制失败');
    }
  };

  // 复制排期
  const copyFn = (data: any) => {
    let str = `${detailData.name as string}\nhttps://www.tapd.cn/41194427/prong/stories/view/${String(detailData.id)}\n`;
    data.forEach((item: PlanType) => {
      str += `${item.title}: ${item.value}\n`;
      if (item.children) {
        item.children.forEach((it: PlanType) => {
          str += `${it.title}: (${it.time as string}) ${it.value}\n`;
        });
      }
    });
    copyPlanFn(str);
  };

  // 详细排期处理Owner
  const handlePlanOwner = (item, obj) => {
    if (obj[item.key] && obj[item.key].value) {
      return `${item.title as string}: ${obj[item.key].value.replace(/小时/g, 'h') as string}\n`;
    }
    return '';
  };

  // 详细排期处理keys为Array
  const handlePlanArray = (item, obj) => {
    const num = item.keys.map((it) => {
      if (obj[it] && obj[it].value) {
        const value = obj[it].value.replace(/小时/g, '');
        return Number(value);
      }
      return 0;
    });
    const v = num.reduce((p: number, n: number) => p + n, 0);
    if (v > 0) {
      return `${item.title as string}: ${v as string}h\n`;
    }
    return '';
  };

  // 详细排期处理开发人员
  const handlePlanUser = (item, obj) => {
    let str = `${item.title as string}：\n`;
    if (obj[item.key] && obj[item.key].children && obj[item.key].children.length) {
      obj[item.key].children.forEach((it: any, i) => {
        str += `${it.title as string}(${it.value.replace(/小时/g, 'h') as string}[${it.time.replace(/至/g, '~') as string}])${i === obj[item.key].children.length - 1 ? '\n' : '、'}`;
      });
      return str;
    }
    return '';
  };

  // 复制详细排期
  const copyDetailFn = (data: any) => {
    const obj: any = {};
    data.forEach((item: PlanType) => {
      obj[item.key] = item;
    });
    let str = `${detailData.name as string}\nhttps://www.tapd.cn/41194427/prong/stories/view/${String(detailData.id)}\n\n排期计划：\n`;
    detailPlanOwner.forEach((item: TypeOf) => {
      str += handlePlanOwner(item, obj);
    });
    detailPlan.forEach((item: any) => {
      str += handlePlanArray(item, obj);
    });
    detailPlanDate.forEach((item: TypeOf) => {
      str += handlePlanOwner(item, obj);
    });
    detailPlanUser.forEach((item: TypeOf) => {
      str += handlePlanUser(item, obj);
    });
    str += `测试范围：\n${obj.testRange.value as string}\n`;
    copyPlanFn(str);
  };

  // 处理阶段时间
  const handleTime = ({ valueRule }, list) => {
    if (valueRule === 'min') {
      const minDate = list.map((it) => it?.taskStartTime).filter(Boolean);
      let minTime = '';
      minDate.forEach((it) => {
        if (!minTime) {
          minTime = it;
        } else {
          minTime = minTime > it ? it : minTime;
        }
      });
      return minTime;
    }
    const maxDate = list.map((it) => it?.taskEndTime).filter(Boolean);
    let maxTime = '';
    maxDate.forEach((it) => {
      if (!maxTime) {
        maxTime = it;
      } else {
        maxTime = maxTime < it ? it : maxTime;
      }
    });
    return maxTime;
  };

  // 获取各个阶段的总时长
  const timeAll = (list: any) => {
    const time = list?.map((it) => Number(it?.taskCost) || 0).reduce((p: number, n: number) => p + n, 0);
    return time ? `${time as string}小时` : '-';
  };

  // 处理时间格式
  const formatTime = (time) => {
    return time ? dayjs(time).format('MM-DD') : '';
  };

  // 处理人员数据
  const handleUser = (data) => {
    let list: any = [];
    if (data && data.length) {
      list = data.map((sub: any, i) => ({
        title: sub.name,
        key: getRandomId(),
        value: sub.taskCost ? `${sub.taskCost as string}小时` : '-',
        time: `${formatTime(sub.taskStartTime)}至${formatTime(sub.taskEndTime)}`,
      }));
      list = list.filter((it) => it.value !== '-');
    }
    return list;
  };

  // 处理阶段副本值数据
  const handleCopy = (k: string, data) => {
    const key = `${k}Vice`;
    let v = data[k];
    if (data[key]) {
      v = data[key];
    }
    return v || '-';
  };

  // 处理阶段标题
  const handleTitle = (t: string) => {
    let k: string = t;
    if (k.indexOf('Vice') > -1) {
      k = k.replace('Vice', '');
    }
    return stageStartTime[k].title;
  };

  // 处理总工时
  const handleTotal = (data) => {
    const time = data?.map((it) => (it?.value !== '-' ? Number(it?.value.replace('小时', '')) : 0)).reduce((p: number, n: number) => p + n, 0);
    return time ? `${time as string}小时` : '-';
  };

  // 处理排期数据
  const handlePlan = (data) => {
    const { developerList, developOwner, developEnv, testArea, timeNodes } = data;
    const obj = {}; // 各阶段人员数据
    const newTimeNodes = { ...timeNodes }; // 阶段时间
    const keys = Object.keys(stageStartTime); // 阶段key
    const userConfigKeys = Object.keys(userConfig); // 人员配置key
    let newPlan = [
      { title: '技术Owner', key: 'index1', value: developOwner || '-' },
      { title: '提测环境', key: 'index2', value: developEnv || '-' },
    ];
    // 阶段数据拆分
    developerList.forEach((item) => {
      if (item.taskList) {
        item.taskList.forEach((it) => {
          if (it.taskType) {
            if (!obj[it.taskType]) {
              obj[it.taskType] = [];
            }
            obj[it.taskType].push({ ...it, name: item.developerName });
          }
        });
      }
    });
    // 各阶段赋值
    keys.forEach((key) => {
      const item = stageStartTime[key];
      const timeList = item.type.map((sub) => obj[sub]).flat();
      newTimeNodes[key] = handleTime(item, timeList);
    });
    // 生成渲染数据
    const dateList: PlanType[] = keys.map((it) => ({ title: handleTitle(it), key: it, value: handleCopy(it, newTimeNodes) }));
    // 生成人员数据
    const userData = userConfigKeys.map((it) => ({
      title: `${userConfig[it] as string}工时`,
      key: `${it}`,
      value: timeAll(obj[it]),
      children: handleUser(obj[it]),
    }));
    // 总工时
    const totalTime = handleTotal(userData);
    const dateUserData = [...dateList, { title: '总工时', key: 'total', value: totalTime }, ...userData].filter((it) => it.value !== '-');
    newPlan = [...newPlan, ...dateUserData, { title: '测试范围', key: 'testRange', value: testArea || '' }];
    return { newSubmitData: { ...data, timeNodes: newTimeNodes }, newPlan };
  };

  // 内容改变
  const handleContentChange = (data) => {
    const { newSubmitData, newPlan } = handlePlan(data);
    setSubmitData(newSubmitData);
    setPlan(newPlan);
  };

  // 关闭弹框
  const closePlanModal = () => {
    setPlanModalOpen(false);
  };

  // 获取排期计划
  const handleGetSchedule = async () => {
    try {
      const res = await getScheduleApi({ storyId: detailData._id });
      handleContentChange(res);
      setSubmitData(res);
    } catch (err) {
      console.log(err);
    }
  };

  // 确认
  const confirmPlan = async (params) => {
    setLoading(true);
    try {
      const res = await submitScheduleApi({ ...params, storyId: detailData._id });
      setLockInfo({ isLock: true });
      setPlanModalOpen(false);
      message.success('操作成功');
      handleGetSchedule();
      setLoading(false);
    } catch (err: any) {
      setLoading(false);
      message.warning(err.message);
    }
  };

  // 确认节点
  const confirmNode = () => {
    setPlanModalOpen(true);
  };

  useEffect(() => {
    if (detailData?.id) {
      handleGetSchedule();
    }
  }, [detailData]);

  return (
    <div className={s.schedulePlan}>
      <SchedulePlanLeft copyDetailFn={copyDetailFn} copyFn={copyFn} data={plan} detailData={detailData} height={height} />
      <SchedulePlanRight handlePlan={handleContentChange} confirmNode={confirmNode} submitData={submitData} lockInfo={lockInfo} />
      {planModalOpen && (
        <PlanModal
          handlePlan={handlePlan}
          submitData={submitData}
          open={planModalOpen}
          onClose={closePlanModal}
          onSubmit={confirmPlan}
          loading={loading}
          copyFn={copyFn}
          copyDetailFn={copyDetailFn}
          plan={plan}
          detailData={detailData}
        />
      )}
    </div>
  );
};

export default React.forwardRef(SchedulePlan);
